package com.biostime.springdraw.common.wechat;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.activiti.engine.impl.util.json.JSONException;
import org.activiti.engine.impl.util.json.JSONObject;
import org.apache.http.Consts;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.log4j.Logger;

import com.biostime.springdraw.common.config.Global;
import com.biostime.springdraw.common.utils.SpringContextHolder;
import com.biostime.springdraw.modules.sd.dao.MemberDao;
import com.biostime.springdraw.modules.sd.entity.Member;
import com.biostime.springdraw.modules.sys.dao.LogDao;
import com.biostime.springdraw.modules.sys.entity.Log;
import com.biostime.springdraw.modules.sys.entity.User;

public class BiostimeWechat {

	/**通过配置项获取域名**/
	public static String Host = Global.getConfig("biostime.wxhost");
	
	/**通过配置项获取域名**/
	public static String mama100Host = Global.getConfig("mama100Host");	
	
	/**
	 * http://wx.biostime.com.cn/bncweixin/service/authorize?encodeTargetUrl=XXXXX   
	 * GET请求
	 * XXXXX是目标地址经过urlencode的字符串
	 * 调完该接口会在目标地址所在页面保存含有用户openId的cookie,从cookie中取得openId
	 */
	public static String OpenId = "http://"+ Host +"/bncweixin/service/authorize?encodeTargetUrl=%s";
	
	/**
	 * http://wx.biostime.com.cn/bncweixin/ftf/getCustInfo   POST请求
	 * POST参数
	 * {"tsno":"144123123123", "openId":"123456"}
	 */
	public static String UserInfo = "http://"+ Host +"/bncweixin/ftf/getCustInfo";
	
	/**
	 *用户的注册登录页面
	 *http://wx.biostime.com.cn/bncweixin/html5/register.html?url=XXXXX
	 *XXXXX是目标地址经过urlencode的字符串
	 *用户注册成功或登录成功后会自动跳转到该目标地址(通常是配置成跳回登录前的页面)
	*/
	public static String Register = "http://"+ Host +"/bncweixin/html5/register.html?url=%s";
	
	/**
	 *mama100用户的注册登录页面
	 *http://www.mama100.com/weixin/bind/auth?token="+$cookies.openId+"&redirect="+encodeURIComponent(window.location.href); 
	 *XXXXX是目标地址经过urlencode的字符串
	 *用户注册成功或登录成功后会自动跳转到该目标地址(通常是配置成跳回登录前的页面)
	*/
	public static String Mama100Register = "http://"+mama100Host+"/weixin/bind/auth?token=%s&redirect=%s ";	
	
	/**4. 
	 *查询还可以抽奖的次数
	 *http://wx.biostime.com.cn/bncweixin/draw   POST请求
	 *POST参数
	 *{"tsno":"144123123123", "openId":"123456"}
	 *含义同2
	*/
	public static String QueryDrawTimes = "http://"+ Host +"/bncweixin/draw/queryDrawTimes";
	
	/**
	 * 减少可以抽奖的次数
	 *http://wx.biostime.com.cn/bncweixin/reduceDrawTimes  POST请求
	 *POST参数
	 *{"tsno":"144123123123", "openId":"123456", "reduceTimes":"1"}
	 *reduceTimes是减少的次数,通常是1.
	 */
	public static String ReduceDrawTimes = "http://"+ Host +"/bncweixin/draw/reduceDrawTimes";
	
	/**
	 * 
	 * 给用户加减积分
	 *http://wx.biostime.com.cn/bncweixin/point/modifyCustomerPoint
	 *举例:
	 *{"tsno":"1234567890","customerId":"123456","point":"5","activityId":"1","sourceSystem":""}
	 *
		@param:
		tsno:		流水号(时间戳)
		customerId:  用户id
		point:       用户增加的积分值
		activityId:  活动编号 (本期积分抽奖活动先填1)
		sourceSystem: 来源系统(10个字符以内,用来标识你们的系统,便于与其他修改积分的系统区分)
		
	 */
	public static String ModifyPoint = "http://"+ Host +"/bncweixin/point/modifyCustomerPoint";	
	
	
	/**
	 * 用户领取优惠券
	 * 	http://wx.biostime.com.cn/bncweixin/coupon/issueCoupon
	 * 举例:
	 * {"tsno":"1234567890","couponDefId":"111","customerId":"123456"}	
	 */
	public static String IssueCoupon = "http://"+ Host +"/bncweixin/coupon/issueCoupon";
	
	/**
	 * 获取jsticket
	 */			
	public static String Jsticket = "http://"+ Host +"/bncweixin/active/jsticket";
	
	/**
	 * 获取AppId
	 */			
	public static String AppID = "http://"+ Host +"/bncweixin/service/appId";	
	
	/**日志打印**/
	public static Logger logger=Logger.getLogger("biostime-api"); 	
		
	
	public static String httpPost(String url, String entity) throws Exception{
		
		System.out.println(url);
		System.out.println(entity);
		
		String res = null;
		
		HttpPost httpPost = new HttpPost(url);
		httpPost.setHeader("Content-Type", "application/json");
		httpPost.setEntity(new StringEntity(entity, Consts.UTF_8));//进行转码  
		
		HttpClient httpClient = HttpClients.createDefault();
		
		HttpResponse httpResponse = httpClient.execute(httpPost);
		
		//状态码
		//int statusCode = httpResponse.getStatusLine().getStatusCode();  
		//System.out.println(statusCode);
		
		//要处理该数据流是否为GZIP流
		InputStream in = httpResponse.getEntity().getContent();
		res = InputStreamToString(in, "utf-8");
		
		return res;
	}
	
	public static String InputStreamToString(InputStream in, String encoding) throws Exception{  
        
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();  
        byte[] data = new byte[BUFFER_SIZE];  
        int count = -1;  
        while((count = in.read(data,0,BUFFER_SIZE)) != -1)  
            outStream.write(data, 0, count);  
          
        data = null;  
        return new String(outStream.toByteArray(), encoding);  
    } 
	
	final static int BUFFER_SIZE = 4096;
	
	
	/**
	 * 内部类
	 * 调用合生元接口的API工具类
	 * @author chenweicheng
	 * @version 2016-04-13
     */	
	public static class Api {
				
		private static LogDao logDao = SpringContextHolder.getBean(LogDao.class);
		
		private static MemberDao memberDao = SpringContextHolder.getBean(MemberDao.class);
		
		/**
	     * 将Json对象转换成Map
	     * @param jsonObject
	     * @return Map对象
	     * @throws JSONException
	     */
	    public static Map<String,String> toMap(String jsonString) throws JSONException {

	        JSONObject jsonObject = new JSONObject(jsonString);
	        
	        Map<String,String> result = new HashMap<String,String>();
	        Iterator<?> iterator = jsonObject.keys();
	        String key = null;
	        String value = null;
	        
	        while (iterator.hasNext()) {

	            key = (String) iterator.next();
	            value = jsonObject.getString(key);
	            result.put(key, value);
	            
	            System.out.println("key:"+key);
	            System.out.println("value:"+value);

	        }
	        return result;
	    }		
				
		/**
		 * 查询用户信息
		 * @author chenweicheng
		 * @version 2016-04-13
	     */		
		public static Map<String,String> getCustomerInfo(String openId){
			Map<String,String> result = null;
			Log log  = new Log();
			String message = null;			
			
			try{
				
				/**新增日志记录**/
				log.setTitle("查询会员信息");
				log.setOutcome("1");
				log.setMethod("post");
				log.setRequestUri(BiostimeWechat.UserInfo);
				log.setRemoteAddr(openId);		
				log.setType("customerInfo");
				log.setCreateBy(new User("1"));
				log.setCreateDate(new Date()); 	
				
				String entity = "{\"tsno\":\"" + new Date().getTime() + "\", \"openId\":\""+ openId +"\"}";
				
				//日志设置请求参数
				log.setUrlParam(entity);				
				
				String res = BiostimeWechat.httpPost(BiostimeWechat.UserInfo, entity);				
				result = toMap(res);
								
				if(result.get("code").equals("100")){
					message = "调用成功";
					log.setOutcome("0");
				}else{
					message = "调用失败,失败原因:"+result.get("desc");
					log.setException(message); 
					log.setException(message); 
					logDao.insert(log);			
				}						
			}catch(Exception ex){
				result = new HashMap<String, String>();
				result.put("code", "-1");
				result.put("desc", ex.getMessage());
				message = "调用失败,出现异常:"+ex.getMessage();
				log.setException(message); 
				log.setException(message); 
				logDao.insert(log);			
			}
			
			logger.info("----------"+log.getTitle()+":"+message+"----------"); 
			
			return result;
		}
				
		/**
		 * 查询会员拥有抽奖次数
		 * @author chenweicheng
		 * @version 2016-04-13
	     */
		public static Map<String,String> queryTimes(String openId){
			Map<String,String> result = null;
			Log log  = new Log();
			String message = null;
			
			try{
				
				/**新增日志记录**/
				log.setTitle("查询用户抽奖机会接口");
				log.setOutcome("1");
				log.setMethod("post");
				log.setRequestUri(BiostimeWechat.QueryDrawTimes);
				log.setRemoteAddr(openId);		
				log.setType("queryTimes");
				log.setCreateBy(new User("1"));
				log.setCreateDate(new Date()); 	
				
				String entity = "{\"tsno\":\"" + new Date().getTime() + "\", \"openId\":\""+ openId +"\"}";
				
				//日志设置请求参数
				log.setUrlParam(entity);
				
				String res = BiostimeWechat.httpPost(BiostimeWechat.QueryDrawTimes, entity);				
				result = toMap(res);
							
				if(result.get("code").equals("100")){
					message = "调用成功";
					log.setOutcome("0");
				}else{
					message = "调用失败,失败原因:"+result.get("desc");
					log.setException(message); 
					logDao.insert(log);			
				}				
			}catch(Exception ex){
				result = new HashMap<String, String>();
				result.put("code", "-1");
				result.put("desc", ex.getMessage());
				message = "调用失败,出现异常:"+ex.getMessage();
				log.setException(message); 
				logDao.insert(log);			
			}
			
			logger.info("----------"+log.getTitle()+":"+message+"----------"); 
			
			return result;
		}

		/**
		 * 减少会员抽奖次数
		 * @author chenweicheng
		 * @version 2016-04-13
	     */
		public static Map<String,String> reduceTimes(String openId){
			Map<String,String> result = null;
			Log log  = new Log();
			String message = null;
			
			try{
				
				/**新增日志记录**/
				log.setTitle("减少会员抽奖次数接口");
				log.setOutcome("1");
				log.setMethod("post");
				log.setRequestUri(BiostimeWechat.ReduceDrawTimes);
				log.setRemoteAddr(openId);		
				log.setType("reduceTimes");
				log.setCreateBy(new User("1"));
				log.setCreateDate(new Date()); 	
				
				String entity2 = "{\"tsno\":\"" + new Date().getTime() + "\", \"openId\":\""+ openId +"\", \"reduceTimes\":1}";		
				
				//日志设置请求参数
				log.setUrlParam(entity2);
				
				String res = BiostimeWechat.httpPost(BiostimeWechat.ReduceDrawTimes, entity2);
				result = toMap(res);
											
				if(result.get("code").equals("100")){
					message = "调用成功";
					log.setOutcome("0");
				}else{
					message = "调用失败,失败原因:"+result.get("desc");					
				}					
			}catch(Exception ex){
				result = new HashMap<String, String>();
				result.put("code", "-1");
				result.put("desc", ex.getMessage()); 
				message = "调用失败,出现异常:"+ex.getMessage();
				log.setException(message); 
				logDao.insert(log);							
			}
			
			logger.info("----------"+log.getTitle()+":"+message+"----------"); 			
			log.setException(message); 
			
			return result;
		}
		
		/**
		 * 给用户加减积分
		 * @author chenweicheng
		 * @version 2016-04-13
		 * @throws Exception 
	     */
		public static Map<String,String> modifyPoint(String openId , String point) throws Exception{ 
			Map<String,String> result = null;
			Log log  = new Log();
			String message = null;
			String sourceSystem = "ismart";
			String activityId = "1";
			
			/**通过openid获取会员信息**/
			Member member = memberDao.getByOpenId(openId);
			
		try{
				
				/**新增日志记录**/
				log.setTitle("给用户加减积分接口");
				log.setOutcome("1");
				log.setMethod("post");
				log.setRequestUri(BiostimeWechat.ModifyPoint);
				log.setRemoteAddr(openId);		
				log.setType("modifyPoint");
				log.setCreateBy(new User("1"));
				log.setCreateDate(new Date()); 		
				
				String entity2 ="{\"tsno\":\"" + new Date().getTime() + "\",\"customerId\":\""+ member.getCustomerid() +"\",\"point\":\""+ point +"\",\"activityId\":\""+ activityId +"\",\"sourceSystem\":\""+sourceSystem+"\"}";	
				
				//日志设置请求参数
				log.setUrlParam(entity2);
				
				String res = BiostimeWechat.httpPost(BiostimeWechat.ModifyPoint, entity2);
				result = toMap(res);
							
				if(result.get("code").equals("100")){
					message = "调用成功";
					log.setOutcome("0");
				}else{
					message = "调用失败,失败原因:"+result.get("desc");
					log.setException(message); 
					logDao.insert(log);			
				}					
			}catch(Exception ex){
				result = new HashMap<String, String>();
				result.put("code", "-1");
				result.put("desc", ex.getMessage()); 
				message = "调用失败,出现异常:"+ex.getMessage();
				log.setException(message); 
				logDao.insert(log);			
			}
			
			logger.info("----------"+log.getTitle()+":"+message+"----------"); 
			
			return result;
		}		
		
		/**
		 * 用户领取优惠券
		 * @author chenweicheng
		 * @version 2016-04-13
		 * @throws Exception 
	     */
		public static Map<String,String> issueCoupon(String openId , String couponDefId) throws Exception{ 
			Map<String,String> result = null;
			Log log  = new Log();
			String message = null;
			
			/**通过openid获取会员信息**/
			Member member = memberDao.getByOpenId(openId);
			
		try{
				
				/**新增日志记录**/
				log.setTitle("用户领取优惠券接口");
				log.setOutcome("1");
				log.setMethod("post");
				log.setRequestUri(BiostimeWechat.IssueCoupon);
				log.setRemoteAddr(openId);		
				log.setType("issueCoupon");
				log.setCreateBy(new User("1"));
				log.setCreateDate(new Date()); 		
				
				String couponCondition = "4";
				
				String entity2 ="{\"tsno\":\"" + new Date().getTime() + "\",\"customerId\":\""+ member.getCustomerid() +"\",\"couponDefId\":\""+couponDefId+"\",\"couponCondition\":\""+couponCondition+"\"}";	
				
				//日志设置请求参数
				log.setUrlParam(entity2);
				
				String res = BiostimeWechat.httpPost(BiostimeWechat.IssueCoupon, entity2);
				result = toMap(res);
							
				if(result.get("code").equals("100") || result.get("code").equals("coupon100")){
					message = "调用成功";
					log.setOutcome("0");
				}
				else {
					message = "调用失败,失败原因:"+result.get("desc");
					log.setException(message); 
					logDao.insert(log);			
				}					
			}catch(Exception ex){
				result = new HashMap<String, String>();
				result.put("code", "-1");
				result.put("desc", ex.getMessage()); 
				message = "调用失败,出现异常:"+ex.getMessage();
				log.setException(message); 
				logDao.insert(log);			
			}
		
			logger.info("----------"+log.getTitle()+":"+message+"----------"); 
			
			return result;
		}				
		
		
	}
}
